<template>
    <div class="user">

        <Row style="margin-top:10px;margin-bottom:10px;">
            <Col span="17">
                <Button class="ivu-btn-default" @click="edit">编辑</Button>
                <Button class="ivu-btn-default" @click="publish">发布</Button>
            </Col>
        </Row>
        <div style="width: 100%; display: flex; justify-content: space-between">
            <div ref="palette"
                 style="width: 100px; margin-right: 2px; background-color: whitesmoke; border: solid 1px black"></div>
            <div ref="diagram" style="flex-grow: 1; height: 550px; border: solid 1px black"></div>
        </div>
        <Modal :draggable="true"
                v-model="modal1"
                title="Common Modal dialog box title"
                @on-ok="ok"
                @on-cancel="cancel"
                :mask-closable="false">
            <p>Content of dialog</p>
            <p>Content of dialog</p>
            <p>Content of dialog</p>
        </Modal>
    </div>
</template>
<script>
    import go from 'gojs';

    var $ = go.GraphObject.make;
    export default {
        name: 'workDefine',
        data () {
            return {
                diagram: null,
                modal1: false,
                diagramData: {
                    'class': 'go.GraphLinksModel',
                    'linkFromPortIdProperty': 'fromPort',
                    'linkToPortIdProperty': 'toPort',
                    'nodeDataArray': [
                        {
                            'category': 'Start',
                            'text': 'Start',
                            'key': -1,
                            'id': '11',
                            'loc': '79.2733400921489 -206.1245513916017'
                        },
                        {
                            'category': 'Conditional',
                            'text': '123',
                            'key': -3,
                            'id': '121',
                            'loc': '200.00622913449305 -206.12455139160136'
                        }
                    ],
                    'linkDataArray': [
                        {
                            'from': -1,
                            'to': -3,
                            'text': 'test',
                            'fromPort': 'R',
                            'toPort': 'L'
                        }
                    ]
                }
            };
        },
        mounted () {
            var self = this;
            var myDiagram =
                $(go.Diagram, this.$refs.diagram,
                    {
                        initialContentAlignment: go.Spot.Center,
                        allowDrop: true, // must be true to accept drops from the Palette
                        layout: $(go.TreeLayout, {angle: 0, arrangement: go.TreeLayout.AlignmentCenterChildren}),
                        'LinkDrawn': this.showLinkLabel, // this DiagramEvent listener is defined below
                        'LinkRelinked': this.showLinkLabel,
                        scrollsPageOnFocus: false,
                        isReadOnly: true,
                        'undoManager.isEnabled': true // enable undo & redo
                    });
            // define the Node templates for regular nodes

            myDiagram.nodeTemplateMap.add('', // the default category
                $(go.Node, 'Table', this.nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, 'Auto',
                        $(go.Shape, 'Rectangle',
                            {fill: '#00A9C9', strokeWidth: 0},
                            new go.Binding('figure', 'figure')),
                        $(go.TextBlock, this.textStyle(),
                            {
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding('text').makeTwoWay())
                    ),
                    // four named ports, one on each side:
                    this.makePort('T', go.Spot.Top, go.Spot.TopSide, false, true),
                    this.makePort('L', go.Spot.Left, go.Spot.LeftSide, true, true),
                    this.makePort('R', go.Spot.Right, go.Spot.RightSide, true, true),
                    this.makePort('B', go.Spot.Bottom, go.Spot.BottomSide, true, false)
                ));
            myDiagram.nodeTemplateMap.add('Conditional',
                $(go.Node, 'Table', this.nodeStyle(),
                    // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
                    $(go.Panel, 'Auto',
                        $(go.Shape, 'Diamond',
                            {fill: '#00A9C9', strokeWidth: 0},
                            new go.Binding('figure', 'figure')),
                        $(go.TextBlock, this.textStyle(),
                            {
                                margin: 8,
                                maxSize: new go.Size(160, NaN),
                                wrap: go.TextBlock.WrapFit,
                                editable: true
                            },
                            new go.Binding('text').makeTwoWay())
                    ),
                    // four named ports, one on each side:
                    this.makePort('T', go.Spot.Top, go.Spot.Top, false, true),
                    this.makePort('L', go.Spot.Left, go.Spot.Left, true, true),
                    this.makePort('R', go.Spot.Right, go.Spot.Right, true, true),
                    this.makePort('B', go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));

            myDiagram.nodeTemplateMap.add('Start',
                $(go.Node, 'Table', this.nodeStyle(),
                    $(go.Panel, 'Auto',
                        $(go.Shape, 'Circle',
                            {minSize: new go.Size(40, 40), fill: '#79C900', strokeWidth: 0}),
                        $(go.TextBlock, 'Start', this.textStyle(),
                            new go.Binding('text'))
                    ),
                    { doubleClick: this.startDoubleClick },
                    // three named ports, one on each side except the top, all output only:
                    this.makePort('L', go.Spot.Left, go.Spot.Left, true, false),
                    this.makePort('R', go.Spot.Right, go.Spot.Right, true, false),
                    this.makePort('B', go.Spot.Bottom, go.Spot.Bottom, true, false)
                ));

            myDiagram.nodeTemplateMap.add('End',
                $(go.Node, 'Table', this.nodeStyle(),
                    $(go.Panel, 'Auto',
                        $(go.Shape, 'Circle',
                            {minSize: new go.Size(40, 40), fill: '#DC3C00', strokeWidth: 0}),
                        $(go.TextBlock, 'End', this.textStyle(),
                            new go.Binding('text'))
                    ),
                    // three named ports, one on each side except the bottom, all input only:
                    this.makePort('T', go.Spot.Top, go.Spot.Top, false, true),
                    this.makePort('L', go.Spot.Left, go.Spot.Left, false, true),
                    this.makePort('R', go.Spot.Right, go.Spot.Right, false, true)
                ));

            myDiagram.nodeTemplateMap.add('Comment',
                $(go.Node, 'Auto', this.nodeStyle(),
                    $(go.Shape, 'File',
                        {fill: '#EFFAB4', strokeWidth: 0}),
                    $(go.TextBlock, this.textStyle(),
                        {
                            margin: 5,
                            maxSize: new go.Size(200, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: 'center',
                            editable: true,
                            font: 'bold 12pt Helvetica, Arial, sans-serif',
                            stroke: '#454545'
                        },
                        new go.Binding('text').makeTwoWay())
                    // no ports, because no links are allowed to connect with a comment
                ));
            myDiagram.linkTemplate =
                $(go.Link,
                    {relinkableFrom: true, relinkableTo: true},
                    $(go.Shape),
                    $(go.Shape, {toArrow: 'OpenTriangle'})
                );

            // initialize the Palette that is on the left side of the page
            var myPalette =
                $(go.Palette, this.$refs.palette, // must name or refer to the DIV HTML element
                    {
                        scrollsPageOnFocus: false,
                        nodeTemplateMap: myDiagram.nodeTemplateMap, // share the templates used by myDiagram
                        model: new go.GraphLinksModel([ // specify the contents of the Palette
                            {category: 'Start', text: 'Start'},
                            {text: 'Step'},
                            {category: 'Conditional', text: '123'},
                            {category: 'End', text: 'End'},
                            {category: 'Comment', text: 'Comment'}
                        ])
                    });
            this.diagram = myDiagram;
            console.log(localStorage.getItem('diagramData'));
            this.diagramData = localStorage.getItem('diagramData') ? JSON.parse(localStorage.getItem('diagramData')) : this.diagramData;
            this.updateModel(this.diagramData);
        },
        watch: {
            modelData: function (val) {
                this.updateModel(val);
            }
        },
        methods: {
            model () {
                return this.diagram.model;
            },
            updateModel (val) {
                // No GoJS transaction permitted when replacing Diagram.model.
                if (val instanceof go.Model) {
                    this.diagram.model = val;
                } else {
                    var m = new go.GraphLinksModel();
                    if (val) {
                        for (var p in val) {
                            m[p] = val[p];
                        }
                    }
                    this.diagram.model = m;
                }
            },
            updateDiagramFromData () {
                this.diagram.startTransaction();
                // This is very general but very inefficient.
                // It would be better to modify the diagramData data by calling
                // Model.setDataProperty or Model.addNodeData, et al.
                this.diagram.updateAllRelationshipsFromData();
                this.diagram.updateAllTargetBindings();
                this.diagram.commitTransaction('updated');
            },
            showLinkLabel (e) {
                var label = e.subject.findObject('LABEL');
                if (label !== null) label.visible = (e.subject.fromNode.data.figure === 'Diamond');
            },
            nodeStyle () {
                return [
                    // The Node.location comes from the "loc" property of the node data,
                    // converted by the Point.parse static method.
                    // If the Node.location is changed, it updates the "loc" property of the node data,
                    // converting back using the Point.stringify static method.
                    new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
                    {
                        // the Node.location is at the center of each node
                        locationSpot: go.Spot.Center
                    }
                ];
            },
            textStyle () {
                return {
                    font: 'bold 11pt Helvetica, Arial, sans-serif',
                    stroke: 'whitesmoke'
                };
            },
            // Define a function for creating a "port" that is normally transparent.
            // The "name" is used as the GraphObject.portId,
            // the "align" is used to determine where to position the port relative to the body of the node,
            // the "spot" is used to control how links connect with the port and whether the port
            // stretches along the side of the node,
            // and the boolean "output" and "input" arguments control whether the user can draw links from or to the port.
            makePort (name, align, spot, output, input) {
                var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);
                // the port is basically just a transparent rectangle that stretches along the side of the node,
                // and becomes colored when the mouse passes over it
                return $(go.Shape,
                    {
                        fill: 'transparent', // changed to a color in the mouseEnter event handler
                        strokeWidth: 0, // no stroke
                        width: horizontal ? NaN : 8, // if not stretching horizontally, just 8 wide
                        height: !horizontal ? NaN : 8, // if not stretching vertically, just 8 tall
                        alignment: align, // align the port on the main Shape
                        stretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),
                        portId: name, // declare this object to be a "port"
                        fromSpot: spot, // declare where links may connect at this port
                        fromLinkable: output, // declare whether the user may draw links from here
                        toSpot: spot, // declare where links may connect at this port
                        toLinkable: input, // declare whether the user may draw links to here
                        cursor: 'pointer', // show a different cursor to indicate potential link point
                        mouseEnter: function (e, port) { // the PORT argument will be this Shape
                            if (!e.diagram.isReadOnly) port.fill = 'rgba(255,0,255,0.5)';
                        },
                        mouseLeave: function (e, port) {
                            port.fill = 'transparent';
                        }
                    });
            },
            edit () {
                this.diagram.isReadOnly = false;
                this.diagram.grid = $(go.Panel, 'Grid',
                    $(go.Shape, 'LineH', {stroke: 'lightgray', strokeWidth: 0.5}),
                    $(go.Shape, 'LineH', {stroke: 'gray', strokeWidth: 0.5, interval: 10}),
                    $(go.Shape, 'LineV', {stroke: 'lightgray', strokeWidth: 0.5}),
                    $(go.Shape, 'LineV', {stroke: 'gray', strokeWidth: 0.5, interval: 10})
                );
            },
            publish () {
                this.diagram.isReadOnly = true;
                this.diagram.grid = $(go.Panel, 'Grid');
                localStorage.setItem('diagramData', this.diagram.model.toJson());
            },
            startDoubleClick (e, obj) {
                var clicked = obj.part;
                if (clicked !== null) {
                    clicked.data.test = '1111';
                }
                this.modal1 = true;
            }
        }
    };
</script>
